package com.bocloud.cmp.service.resource;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.bocloud.cmp.dao.BucketDao;
import com.bocloud.cmp.dao.CloudVendorDao;
import com.bocloud.cmp.dao.RegionDao;
import com.bocloud.cmp.driver.providers.intf.BucketProvider;
import com.bocloud.cmp.entity.resource.Bucket;
import com.bocloud.cmp.entity.resource.CloudVendor;
import com.bocloud.cmp.entity.resource.Region;
import com.bocloud.cmp.interfaces.resource.BucketService;
import com.bocloud.cmp.model.BucketBean;
import com.bocloud.common.enums.BaseStatus;
import com.bocloud.common.model.BsmResult;
import com.bocloud.common.model.GridBean;
import com.bocloud.common.model.Param;
import com.bocloud.common.utils.Common;
import com.bocloud.common.utils.GridHelper;
import com.bocloud.common.utils.JSONTools;
import com.bocloud.coordinator.harmony.HarmonyLock;
import com.bocloud.coordinator.harmony.LockFactory;
import com.google.common.collect.Maps;

/**
 * Bucket Service接口实现
 * 
 * @author dongkai
 *
 */
@Service("bucketService")
public class BucketServiceImpl implements BucketService {

	private static Logger logger = LoggerFactory.getLogger(BucketServiceImpl.class);
	@Autowired
	private LockFactory lockFactory;
	@Autowired
	private BucketDao bucketDao;
	@Autowired
	private RegionDao regionDao;
	@Autowired
	private CloudVendorDao cloudVendorDao;
	@Autowired
	private BucketProvider bucketProvider;

	@Override
	public BsmResult list(int page, int rows, List<Param> params, Map<String, String> sorter, Boolean simple) {
		try {
			GridBean gridBean = null;
			if (null == params) {
				params = new ArrayList<>();
			}
			if (null == sorter) {
				sorter = Maps.newHashMap();
			}
			sorter.put("gmtCreate", Common.ONE);
			List<Bucket> list = bucketDao.list(page, rows, params, sorter);
			for (Bucket bucket : list) {
				Region region = regionDao.query(bucket.getRegion());
				CloudVendor cloudVendor = cloudVendorDao.query(bucket.getVendorId());
				if (null != region && null != cloudVendor) {
					bucket.setRegionName(region.getName());
					bucket.setVendorName(cloudVendor.getName());
				}
			}
			int total = bucketDao.count(params);
			gridBean = GridHelper.getBean(page, rows, total, list);
			return new BsmResult(true, gridBean, "查询成功");
		} catch (Exception e) {
			logger.error("list bucket failure:", e);
			return new BsmResult(false, "查询失败", null, null);
		}
	}

	@Override
	public BsmResult create(String params, Long userId) {
		JSONObject object = JSONTools.isJSONObj(params);
		Long id = object.getLong(Common.ID);
		Long region = object.getLong(Common.REGION);
		String name = object.getString(Common.NAME);
		Boolean acl = object.getBoolean("acl");
		String remark = object.getString("remark");
		try {
			CloudVendor cloudVendor = cloudVendorDao.query(id);
			Region reg = regionDao.query(region);
			if (null == cloudVendor || null == reg) {
				logger.error("get cloudvendor and region failure");
				return new BsmResult(false, "创建失败!");
			}
			BsmResult bsmResult = bucketProvider.create(name, acl, cloudVendor.getUuid(), reg.getCode());
			if (null == bsmResult || !bsmResult.isSuccess()) {
				return new BsmResult(false, "创建失败,名称可能重复!");
			}
			Bucket bucket = JSONObject.parseObject(bsmResult.getData().toString(), Bucket.class);
			bucket.setRemark(remark);
			bucket.setStatus(BaseStatus.NORMAL.name());
			bucket.setRegion(region);
			bucket.setVendorId(id);
			bucket.setCreaterId(userId);
			bucketDao.save(bucket);
			return new BsmResult(true, "创建成功!");
		} catch (Exception e) {
			logger.error("save bucket failure:", e);
			return new BsmResult(false, "创建失败");
		}
	}

	@Override
	public BsmResult remove(Long id, Long userId) {
		String path = Bucket.class.getSimpleName() + "_" + id;
		HarmonyLock lock = null;
		Boolean result = false;
		try {
			lock = lockFactory.getLock(path);
			if (!lock.acquire(path, 10, TimeUnit.SECONDS)) {
				logger.warn("Get harmonyLock time out!");
				return new BsmResult(false, "请求超时", "", "");
			}
			Bucket bucket = bucketDao.query(id);
			if (null == bucket) {
				logger.warn("bucket data not exist");
				return new BsmResult(false, "数据不存在", "", "");
			}
			CloudVendor cloudVendor = cloudVendorDao.query(bucket.getVendorId());
			Region reg = regionDao.query(bucket.getRegion());
			if (null == cloudVendor || null == reg) {
				logger.error("get cloudVendor and reg failure");
				return new BsmResult(false, "删除失败", "", "");
			}
			BsmResult bsmResult = bucketProvider.remove(bucket.getName(), cloudVendor.getUuid(), reg.getCode());
			if (null == bsmResult || !bsmResult.isSuccess()) {
				return new BsmResult(false, "删除失败!");
			}
			result = bucketDao.remove(id, userId);
		} catch (Exception e) {
			logger.error("remove bucket fail:", e);
			return new BsmResult(false, "删除失败!", "", "");
		} finally {
			if (null != lock) {
				lock.release();
			}
		}
		return result ? new BsmResult(true, "删除成功") : new BsmResult(false, "删除失败!", "", "");
	}

	@Override
	public BsmResult sync(Long id, Long region, Long userId) {
		try {
			CloudVendor cloudVendor = cloudVendorDao.query(id);
			Region reg = regionDao.query(region);
			if (null == cloudVendor || null == reg) {
				logger.error("get cloudVendor and reg failure!");
				return new BsmResult(false, "同步失败!");
			}
			// 启动一个线程从MQ上获取数据
			new Thread(new Runnable() {
				@Override
				public void run() {
					try {
						BsmResult bsmResult = bucketProvider.list(cloudVendor.getUuid(), reg.getCode());
						if (null != bsmResult.getData()) {
							String content = JSONObject.toJSONString(bsmResult.getData());
							JSONArray result = JSONArray.parseArray(content);
							List<Bucket> buckets = bucketDao.listByVendorId(id);
							List<Bucket> resultData = new ArrayList<>();
							resultData.addAll(buckets);
							for (Object obj : result) {
								boolean flag = true;
								BucketBean bean = JSONObject.parseObject(obj.toString(), BucketBean.class);
								for (Bucket bucket : buckets) {
									if (bean.getName().equals(bucket.getName())) {
										flag = false;
										BeanUtils.copyProperties(bean, bucket);
										bucketDao.update(bucket);
										resultData.remove(bucket);
									}
								}
								if (flag) {
									Bucket bucket = JSONObject.parseObject(obj.toString(), Bucket.class);
									Region region = regionDao.getByRegionId(bucket.getRegionId(), cloudVendor.getId());
									if (null != region) {
										bucket.setRegion(region.getId());
									}
									bucket.setCreaterId(userId);
									bucket.setStatus(BaseStatus.NORMAL.name());
									bucket.setVendorId(id);
									bucketDao.save(bucket);
								}
							}
							for (Bucket bucket : resultData) {
								bucketDao.remove(bucket.getId(), userId);
							}
						}
					} catch (Exception e) {
						logger.error("Get Message Exception:", e);
					}
				}
			}).start();
			return new BsmResult(true, "同步任务已经下发，正在执行……");
		} catch (Exception e) {
			logger.error("sync failure:", e);
			return new BsmResult(false, "同步失败!");
		}
	}

	@Override
	public BsmResult detail(Long id) {
		try {
			Bucket bucket = bucketDao.query(id);
			Region region = regionDao.query(bucket.getRegion());
			CloudVendor cloudVendor = cloudVendorDao.query(bucket.getVendorId());
			if (null != region && null != cloudVendor) {
				bucket.setRegionName(region.getName());
				bucket.setVendorName(cloudVendor.getName());
			}
			return new BsmResult(true, bucket, "查询详情成功");
		} catch (Exception e) {
			logger.error("query bucket detail fail:", e);
			return new BsmResult(false, "查询详情失败", "", "");
		}
	}

}
